package main

import (
	"compress/gzip"
	du "downloadDanceVideo/downloadUtils"
	logger "downloadDanceVideo/logutils"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"strconv"
	"strings"
)

// formatRequest generates ascii representation of a request
func formatRequest(r *http.Request) string {
	// Create return string
	var request []string
	// Add the request string
	url := fmt.Sprintf("%v %v %v", r.Method, r.URL, r.Proto)
	request = append(request, url)
	// Add the host
	request = append(request, fmt.Sprintf("Host: %v", r.Host))
	// Loop through headers
	for name, headers := range r.Header {
		name = strings.ToLower(name)
		for _, h := range headers {
			request = append(request, fmt.Sprintf("%v: %v", name, h))
		}
	}

	// If this is a POST, add post data
	if r.Method == "POST" {
		r.ParseForm()
		request = append(request, "\n")
		request = append(request, r.Form.Encode())
	}
	// Return the request as a string
	return strings.Join(request, "\n")
}

func parseOutRealDownloadUrl(fakeUrl string) string {
	rt := ""

	// Declare http client
	client := &http.Client{}

	// Declare HTTP Method and Url
	req, err := http.NewRequest("GET", fakeUrl, nil)

	if err != nil {
		panic("parseOutRealDownloadUrl request(http.NewRequest) error")
	}

	//issue the request
	resp, err := client.Do(req)

	if err != nil {
		panic("parseOutRealDownloadUrl request(client.Do) error")
	}

	//manually uncompress response body
	var reader io.ReadCloser
	if resp.Header.Get("Content-Encoding") == "gzip" {
		reader, err = gzip.NewReader(resp.Body)
		if err != nil {
			panic("parseOutRealDownloadUrl manually uncompress response body error")
		}
	} else {
		reader = resp.Body
	}

	// Read response
	data, err := ioutil.ReadAll(reader)
	if err != nil {
		panic("parseOutRealDownloadUrl ioutil.ReadAll(reader) error")
	}
	//fmt.Println(data)

	var raw map[string]interface{}
	json.Unmarshal(data, &raw)

	fmt.Print("parseOutRealDownloadUrl->")
	fmt.Println(raw["success"], raw["type"], raw["url"])

	rt = raw["url"].(string)
	return rt
}

func main() {
	pagePtr := flag.Int("page", 0, "The page Number to download.Must be greater than 0 and increase by 20.")
	flag.Parse()

	logger.Init()
	logger.MULTITRACE.Println("main starts.")

	arg_num := len(os.Args)
	logger.MULTITRACE.Println("the num of input is ", arg_num)

	page := *pagePtr

	if page%20 == 0 && page > 0 {

	} else {
		logger.MULTITRACE.Println("page is ", page)
		panic("page is illigal. Use -h to find out the usage.")
	}

	// Declare http client
	client := &http.Client{}

	// Declare HTTP Method and Url
	req, err := http.NewRequest("GET", "http://42.121.252.29/v5/search/srchn.json", nil)

	//Set header
	req.Header.Set("Host", "www.feixun.tv")
	req.Header.Set("Connection", "Keep-Alive")
	req.Header.Set("Accept-Encoding", "gzip")
	req.Header.Set("User-Agent", "okhttp/2.7.5")

	q := req.URL.Query()
	q.Add("platform", "and")
	q.Add("order", "all")
	q.Add("sid", "866333024898862")
	q.Add("appVersion", "5.1.0")
	q.Add("size", "20")
	q.Add("brand", "LeEco")
	q.Add("q", "热舞")
	q.Add("osVersion", "23")
	q.Add("type", "video")
	q.Add("partner", "0005")
	q.Add("appName", "general_video")
	q.Add("model", "Le X620")
	q.Add("start", strconv.Itoa(page))

	req.URL.RawQuery = q.Encode()

	// Set cookie
	//req.Header.Set("Cookie", "name=xxxx; count=x")

	//issue the request
	resp, err := client.Do(req)

	logger.MULTITRACE.Println(formatRequest(req))
	logger.MULTITRACE.Println(" ")
	//panic("debug")

	//manually uncompress response body
	var reader io.ReadCloser
	if resp.Header.Get("Content-Encoding") == "gzip" {
		reader, err = gzip.NewReader(resp.Body)
		if err != nil {
			return
		}
	} else {
		reader = resp.Body
	}

	// Read response
	data, err := ioutil.ReadAll(reader)

	// error handle
	if err != nil {
		logger.MULTITRACE.Println("error = %s \n", err)
	}

	// Print response
	//logger.MULTITRACE.Println("Response = %s", string(data))

	var raw map[string]interface{}
	json.Unmarshal(data, &raw)

	logger.MULTITRACE.Println(raw["last_pos"])

	srArrays := raw["sr"].([]interface{})

	for _, item := range srArrays {
		//logger.MULTITRACE.Println(index, item)
		itemArrays := item.(map[string]interface{})

		for k, v := range itemArrays {
			//logger.MULTITRACE.Println(k, v)
			if k == "video" {
				videoItems := v.(map[string]interface{})
				title := ""
				fakeDownloadUrl := ""
				for k2, v2 := range videoItems {
					//logger.MULTITRACE.Println(k2, v2)
					if k2 == "title" {
						title = v2.(string)
					} else if k2 == "download_url" {
						fakeDownloadUrl = v2.(string)
					} else {
						//nothing
					}
				}
				logger.MULTITRACE.Println(title)
				logger.MULTITRACE.Println(fakeDownloadUrl)
				realUrl := parseOutRealDownloadUrl(fakeDownloadUrl)
				du.DownloadFromUrl(realUrl, title)

				logger.MULTITRACE.Println("======")
				logger.MULTITRACE.Println("======")
				logger.MULTITRACE.Println("======")
			}
		}
	}

	logger.MULTITRACE.Println("download page number is :", page, " Size is 20")
	logger.MULTITRACE.Println("main finished.")
}
